package br.com.intelsys.basics.action;

import java.util.Calendar;
import java.util.Date;

/**
 * Representa um cookie na aplicacao web
 * 
 * Esta classe foi criada para encapsular o uso da javax.servlet.http.Cookie
 * para nao deixar a aplicacao ver a implementacao dos Servlets
 * 
 * Para manipular esta classe deve-se usar o List que o SystemAction fornece.
 * Ele eh a interface implementada pelo CookieList, quem realmente manipula os
 * cookies junto ao Response e Request das implementacoes dos Servlets
 * 
 * @author Patrick Givisiez
 * 
 */

public class Cookie {
	private javax.servlet.http.Cookie cookie;

	Cookie(javax.servlet.http.Cookie cookie) {
		this.cookie = cookie;
	}

	/**
	 * Constructs a cookie with a specified name and value.
	 * 
	 * <p>
	 * The name must conform to RFC 2109. That means it can contain only ASCII
	 * alphanumeric characters and cannot contain commas, semicolons, or white
	 * space or begin with a $ character. The cookie's name cannot be changed
	 * after creation.
	 * 
	 * <p>
	 * The value can be anything the server chooses to send. Its value is
	 * probably of interest only to the server. The cookie's value can be
	 * changed after creation with the <code>setValue</code> method.
	 * 
	 * <p>
	 * By default, cookies are created according to the Netscape cookie
	 * specification. The version can be changed with the
	 * <code>setVersion</code> method.
	 * 
	 * 
	 * @param name
	 *            a <code>String</code> specifying the name of the cookie
	 * 
	 * @param value
	 *            a <code>String</code> specifying the value of the cookie
	 * 
	 * @throws IllegalArgumentException
	 *             if the cookie name contains illegal characters (for example,
	 *             a comma, space, or semicolon) or it is one of the tokens
	 *             reserved for use by the cookie protocol
	 * @see #setValue
	 * @see #setVersion
	 * 
	 */
	public Cookie(String name, String value) {
		this.cookie = new javax.servlet.http.Cookie(name, value);
	}

	javax.servlet.http.Cookie getServletCookie() {
		return (this.cookie);
	}

	/**
	 * Returns the comment describing the purpose of this cookie, or
	 * <code>null</code> if the cookie has no comment.
	 * 
	 * @return a <code>String</code> containing the comment, or
	 *         <code>null</code> if none
	 * 
	 * @see #setComment
	 * 
	 */
	public String getComment() {
		return (this.cookie.getComment());
	}

	/**
	 * Returns the domain name set for this cookie. The form of the domain name
	 * is set by RFC 2109.
	 * 
	 * @return a <code>String</code> containing the domain name
	 * 
	 * @see #setDomain
	 * 
	 */
	public String getDomain() {
		return (this.cookie.getDomain());
	}

	/**
	 * Returns the maximum age of the cookie, specified in seconds, By default,
	 * <code>-1</code> indicating the cookie will persist until browser
	 * shutdown.
	 * 
	 * 
	 * @return an integer specifying the maximum age of the cookie in seconds;
	 *         if negative, means the cookie persists until browser shutdown
	 * 
	 * 
	 * @see #setMaxAge
	 * 
	 */
	public int getMaxAge() {
		return (this.cookie.getMaxAge());
	}

	/**
	 * Returns the name of the cookie. The name cannot be changed after
	 * creation.
	 * 
	 * @return a <code>String</code> specifying the cookie's name
	 * 
	 */
	public String getName() {
		return (this.cookie.getName());
	}

	/**
	 * Returns the path on the server to which the browser returns this cookie.
	 * The cookie is visible to all subpaths on the server.
	 * 
	 * 
	 * @return a <code>String</code> specifying a path that contains a servlet
	 *         name, for example, <i>/catalog</i>
	 * 
	 * @see #setPath
	 * 
	 */
	public String getPath() {
		return (this.cookie.getPath());
	}

	/**
	 * Returns <code>true</code> if the browser is sending cookies only over a
	 * secure protocol, or <code>false</code> if the browser can send cookies
	 * using any protocol.
	 * 
	 * @return <code>true</code> if the browser uses a secure protocol;
	 *         otherwise, <code>true</code>
	 * 
	 * @see #setSecure
	 * 
	 */
	public boolean getSecure() {
		return (this.cookie.getSecure());
	}

	/**
	 * Returns the value of the cookie.
	 * 
	 * @return a <code>String</code> containing the cookie's present value
	 * 
	 * @see #setValue
	 * @see Cookie
	 * 
	 */
	public String getValue() {
		return (this.cookie.getValue());
	}

	/**
	 * Returns the version of the protocol this cookie complies with. Version 1
	 * complies with RFC 2109, and version 0 complies with the original cookie
	 * specification drafted by Netscape. Cookies provided by a browser use and
	 * identify the browser's cookie version.
	 * 
	 * 
	 * @return 0 if the cookie complies with the original Netscape
	 *         specification; 1 if the cookie complies with RFC 2109
	 * 
	 * @see #setVersion
	 * 
	 */
	public int getVersion() {
		return (this.cookie.getVersion());
	}

	/**
	 * 
	 * Specifies a comment that describes a cookie's purpose. The comment is
	 * useful if the browser presents the cookie to the user. Comments are not
	 * supported by Netscape Version 0 cookies.
	 * 
	 * @param purpose
	 *            a <code>String</code> specifying the comment to display to the
	 *            user
	 * 
	 * @see #getComment
	 * 
	 */
	public void setComment(String purpose) {
		this.cookie.setComment(purpose);
	}

	/**
	 * 
	 * Specifies the domain within which this cookie should be presented.
	 * 
	 * <p>
	 * The form of the domain name is specified by RFC 2109. A domain name
	 * begins with a dot (<code>.foo.com</code>) and means that the cookie is
	 * visible to servers in a specified Domain Name System (DNS) zone (for
	 * example, <code>www.foo.com</code>, but not <code>a.b.foo.com</code>). By
	 * default, cookies are only returned to the server that sent them.
	 * 
	 * 
	 * @param pattern
	 *            a <code>String</code> containing the domain name within which
	 *            this cookie is visible; form is according to RFC 2109
	 * 
	 * @see #getDomain
	 * 
	 */
	public void setDomain(String pattern) {
		this.cookie.setDomain(pattern);
	}

	/**
	 * Sets the maximum age of the cookie in seconds.
	 * 
	 * <p>
	 * A positive value indicates that the cookie will expire after that many
	 * seconds have passed. Note that the value is the <i>maximum</i> age when
	 * the cookie will expire, not the cookie's current age.
	 * 
	 * <p>
	 * A negative value means that the cookie is not stored persistently and
	 * will be deleted when the Web browser exits. A zero value causes the
	 * cookie to be deleted.
	 * 
	 * @param expiry
	 *            an integer specifying the maximum age of the cookie in
	 *            seconds; if negative, means the cookie is not stored; if zero,
	 *            deletes the cookie
	 * 
	 * 
	 * @see #getMaxAge
	 * 
	 */
	public void setMaxAge(int expiry) {
		this.cookie.setMaxAge(expiry);
	}

	/**
	 * Define quando um cookie ira expirar
	 * 
	 * O tempo que ele permanecera sera a quantidade de segundos apos a chamada
	 * deste metodo.
	 * 
	 * Se for informado um valor nulo, o cookie sera apagado. Se for um
	 * 
	 * @param expiry
	 *            Quantos segundos ate a data informada. Se for um valor nulo ou
	 *            que provoque o resultado de zero segundos, o cookie sera
	 *            apagado; se for uma data anterior a agora, gerando um valor
	 *            negativo, o cookie nao sera guardado; se for uma data
	 *            posterior a agora, gerando um valor positivo, o cookie sera
	 *            guardado normalmente.
	 */
	public void setMaxAge(Date expiry) {
		if (expiry == null) {
			this.setMaxAge(0);
		} else {
			Date d = new Date();
			this.setMaxAge(((int) (expiry.getTime() - d.getTime())) / 1000);
		}

	}

	/**
	 * Define quando um cookie ira expirar
	 * 
	 * O tempo que ele permanecera sera a quantidade de segundos apos a chamada
	 * deste metodo.
	 * 
	 * Se for informado um valor nulo, o cookie sera apagado. Se for um
	 * 
	 * @param expiry
	 *            Quantos segundos ate a data informada. Se for um valor nulo ou
	 *            que provoque o resultado de zero segundos, o cookie sera
	 *            apagado; se for uma data anterior a agora, gerando um valor
	 *            negativo, o cookie nao sera guardado; se for uma data
	 *            posterior a agora, gerando um valor positivo, o cookie sera
	 *            guardado normalmente.
	 */
	public void setMaxAge(Calendar expiry) {
		if (expiry == null) {
			this.setMaxAge(0);
		} else {
			this.setMaxAge(expiry.getTime());
		}
	}

	/**
	 * Specifies a path for the cookie to which the client should return the
	 * cookie.
	 * 
	 * <p>
	 * The cookie is visible to all the pages in the directory you specify, and
	 * all the pages in that directory's subdirectories. A cookie's path must
	 * include the servlet that set the cookie, for example, <i>/catalog</i>,
	 * which makes the cookie visible to all directories on the server under
	 * <i>/catalog</i>.
	 * 
	 * <p>
	 * Consult RFC 2109 (available on the Internet) for more information on
	 * setting path names for cookies.
	 * 
	 * 
	 * @param uri
	 *            a <code>String</code> specifying a path
	 * 
	 * 
	 * @see #getPath
	 * 
	 */
	public void setPath(String uri) {
		this.cookie.setPath(uri);
	}

	/**
	 * Indicates to the browser whether the cookie should only be sent using a
	 * secure protocol, such as HTTPS or SSL.
	 * 
	 * <p>
	 * The default value is <code>false</code>.
	 * 
	 * @param flag
	 *            if <code>true</code>, sends the cookie from the browser to the
	 *            server only when using a secure protocol; if
	 *            <code>false</code>, sent on any protocol
	 * 
	 * @see #getSecure
	 * 
	 */
	public void setSecure(boolean flag) {
		this.cookie.setSecure(flag);
	}

	/**
	 * 
	 * Assigns a new value to a cookie after the cookie is created. If you use a
	 * binary value, you may want to use BASE64 encoding.
	 * 
	 * <p>
	 * With Version 0 cookies, values should not contain white space, brackets,
	 * parentheses, equals signs, commas, double quotes, slashes, question
	 * marks, at signs, colons, and semicolons. Empty values may not behave the
	 * same way on all browsers.
	 * 
	 * @param newValue
	 *            a <code>String</code> specifying the new value
	 * 
	 * 
	 * @see #getValue
	 * @see Cookie
	 * 
	 */
	public void setValue(String newValue) {
		this.cookie.setValue(newValue);
	}

	/**
	 * Sets the version of the cookie protocol this cookie complies with.
	 * Version 0 complies with the original Netscape cookie specification.
	 * Version 1 complies with RFC 2109.
	 * 
	 * <p>
	 * Since RFC 2109 is still somewhat new, consider version 1 as experimental;
	 * do not use it yet on production sites.
	 * 
	 * 
	 * @param v
	 *            0 if the cookie should comply with the original Netscape
	 *            specification; 1 if the cookie should comply with RFC 2109
	 * 
	 * @see #getVersion
	 * 
	 */
	public void setVersion(int v) {
		this.cookie.setVersion(v);
	}
}
